package tasks

import (
	"time"

	enumsspb "go.temporal.io/server/api/enums/v1"
	persistencespb "go.temporal.io/server/api/persistence/v1"
	"go.temporal.io/server/common/definition"
)

// ChasmTaskPure is a task that applies a batch of state changes to a CHASM
// entity. All components within the entity's tree will have their pending state
// changes applied.
type ChasmTaskPure struct {
	definition.WorkflowKey // Task interface assumes WorkflowKey.
	VisibilityTimestamp    time.Time
	TaskID                 int64
	Category               Category // Set based on the task's queue.
}

var _ Task = &ChasmTaskPure{}

func (t *ChasmTaskPure) GetTaskID() int64 {
	return t.TaskID
}

func (t *ChasmTaskPure) SetTaskID(id int64) {
	t.TaskID = id
}

func (t *ChasmTaskPure) GetVisibilityTime() time.Time {
	return t.VisibilityTimestamp
}

func (t *ChasmTaskPure) SetVisibilityTime(timestamp time.Time) {
	t.VisibilityTimestamp = timestamp
}

func (t *ChasmTaskPure) GetCategory() Category {
	return t.Category
}

func (t *ChasmTaskPure) GetType() enumsspb.TaskType {
	return enumsspb.TASK_TYPE_CHASM_PURE
}

func (t *ChasmTaskPure) GetKey() Key {
	if t.GetCategory().Type() == CategoryTypeScheduled {
		return NewKey(t.VisibilityTimestamp, t.TaskID)
	}

	return NewImmediateKey(t.TaskID)
}

// ChasmTask is a task with side effects generated by a CHASM component.
type ChasmTask struct {
	definition.WorkflowKey // Task interface assumes WorkflowKey.
	VisibilityTimestamp    time.Time
	TaskID                 int64
	Category               Category // Set based on the task's queue.
	Destination            string   // Set for outbound tasks.
	Info                   *persistencespb.ChasmTaskInfo
}

var _ Task = &ChasmTask{}

func (t *ChasmTask) GetCategory() Category {
	return t.Category
}

func (t *ChasmTask) GetType() enumsspb.TaskType {
	return enumsspb.TASK_TYPE_CHASM
}

func (t *ChasmTask) GetKey() Key {
	if t.GetCategory().Type() == CategoryTypeScheduled {
		return NewKey(t.VisibilityTimestamp, t.TaskID)
	}

	return NewImmediateKey(t.TaskID)
}

func (t *ChasmTask) GetTaskID() int64 {
	return t.TaskID
}

func (t *ChasmTask) SetTaskID(id int64) {
	t.TaskID = id
}

func (t *ChasmTask) GetVisibilityTime() time.Time {
	return t.VisibilityTimestamp
}

func (t *ChasmTask) SetVisibilityTime(timestamp time.Time) {
	t.VisibilityTimestamp = timestamp
}
